#include "bsp.h"
#include "mrfi.h"
#include "bsp_leds.h"
#include "bsp_buttons.h"
#include "nwk_types.h"
#include "nwk_api.h"
#include "nwk_frame.h"
#include "nwk.h"
#include "vlo_rand.h"
#include "cod_errores.h"

void Init();
void TXString( char* cadena, int largo );

static          linkID_t sLinkIDNC = 0;
static          uint8_t  sRxTid = 0;

static uint8_t sRxCallback(linkID_t port);


// nodo movil X
int main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
  
  Init();


  
  // inicializo el kit
  BSP_Init();

  // testeo el aviso de warning 0
  TODOOK
  /*
  while(1){
    clearError();
    if(BSP_BUTTON1()){
      signalError(1);
      break;
    }
  }
  */
    
  // para debuggear...hago constar que es el nodo X  
  TXString("NODO X",6);
  
// levanto la radio -----------------------------------------------
  addr_t lAddr;
  
  // direccion del nodo X 
  lAddr.addr[0]=0xAB;
  lAddr.addr[1]=0;
  lAddr.addr[2]=0;
  lAddr.addr[3]=10;
  //----------------------
  // seteo la direccion del modulo
  // OJO que hay que reprogramar!!!!
  SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr);
  
  
  
  // esta llamada devuelve un fail, porque no es la idea que levante nada
  SMPL_Init(sRxCallback);
  
 
  // termine de levantar la radio
  TODOOK
       
     while (1)
     {
       // espero a que me llame el nodo central...
        if (SMPL_SUCCESS == SMPL_LinkListen(&sLinkIDNC))
        {
          break;
        }
        //signalError(0);
        // hago parpadear el led verde
        BSP_TOGGLE_LED2();
      }

     // hay conexion
     signalError(0);
  
  
  // variables para ver la informacion de la senal.
  // el buffer de recepcion es el mayor tamano del payload que se puede
  // enviar.
  ioctlRadioSiginfo_t sigInfo;
  uint8_t     msg[MAX_APP_PAYLOAD], len;
  
  msg[0] = 't';
  msg[1] = 'x';
  msg[2] = 'N';
  msg[3] = 'X';
  
  len = 4;
  while(1){
    // EMPIEZA EL PROTOCOLO PROPIAMENTE DICHO!
    if(SMPL_SUCCESS == SMPL_Send(sLinkIDNC,msg,len)){
      //signalError(0);    
      TXString("txNC",len);
      TODOOK;
    }
    else{
      //signalError(4);
    }
    
  }
  /*
  if (SMPL_Receive(sLinkIDNC, msg, &len) == SMPL_SUCCESS)
    
  {
    while(1){
      
      sigInfo.lid = sLinkIDNC;
      SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SIGINFO, (void *)&sigInfo);
      msg[0] = (char)sigInfo.sigInfo[0]+48;
      TXString( msg,1);
      
      BSP_TOGGLE_LED2();
      
      TODOOK;
    }
    
    BSP_TOGGLE_LED1();
  
  }
  */
    

  return 0;
}

// ------------------------------------------------------------------
// transmito por el puerto serie
//
void TXString( char* cadena, int largo )
{
  int puntero;
  for( puntero = 0; puntero < largo; puntero++){
    UCA0TXBUF = cadena[puntero];
    while (!(IFG2&UCA0TXIFG));              // espero a que termine de enviar
  }
}

// -------------------------------------------------
// CALLBACK que pide simpliciTI
//
static uint8_t sRxCallback(linkID_t port){
  uint8_t msg[2], len, tid;

  /* is the callback for the link ID we want to handle? */
  if (port == sLinkIDNC)
  {
    /* yes. go get the frame. we know this call will succeed. */
     if ((SMPL_SUCCESS == SMPL_Receive(sLinkIDNC, msg, &len)) && len)
     {
       /* Check the application sequence number to detect
        * late or missing frames...
        */
       tid = *(msg+1);
       if (tid)
       {
         if (tid > sRxTid)
         {
           signalError(2);
         }
       }
       else
       {
         /* wrap case... */
         if (sRxTid)
         {
            signalError(10);
         }
       }
     }
  }
  /* keep frame for later handling */
  return 0;
}

//---------------------------------------------------------------------------
// INICIALIZACION DEL SISTEMA
//
void Init()
{
    // SimpliciTI igual los cambia...
  P1DIR = 0xFB;
  P1OUT = 0x00;
  P2DIR = 0x27;
  P2OUT = 0x00;
  P3DIR = 0xC0;
  P3OUT = 0x00;
  P4DIR = 0xFF;
  P4OUT = 0x00;
  
  
  
  BCSCTL1 = CALBC1_8MHZ;                    // Set DCO
  DCOCTL = CALDCO_8MHZ;
  
  BCSCTL3 |= LFXT1S_2;                      // LFXT1 = VLO
  TACCTL0 = CCIE;                           // TACCR0 interrupt enabled
  TACCR0 = 12000;                           // ~1 second
  TACTL = TASSEL_1 + MC_1;                  // ACLK, upmode
  
  P3SEL |= 0x30;                            // P3.4,5 = USCI_A0 TXD/RXD
  UCA0CTL1 = UCSSEL_2;                      // SMCLK
  UCA0BR0 = 0x41;                           // 9600 from 8Mhz
  UCA0BR1 = 0x3;
  UCA0MCTL = UCBRS_2;                       
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt
  __enable_interrupt(); 
}

//------------------------------------------------------------------------------
// Timer A0 ISR
//
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
  // reservado para hacer el polling...
}


///------------------------------------------------------------------------------
// USCIA ISR
//
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
  
  // me preparo para recibir comandos...
  
  char rx = UCA0RXBUF;
  if ( rx == 'b' || rx == 'B' )  // buscar nodo
  {
  }
  else if ( rx == 'S' || rx == 's' ) // S iempre encendido
  {
  }
  else if ( rx == 'A' || rx == 'a' ) // A pagar, o A dormir
  {
  }
}